package com.xbongbong.paas.log.model.impl;

import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.log.MongoLogUtil;
import com.xbongbong.paas.log.MongoQueryConditions;
import com.xbongbong.paas.log.entity.LoginLogEntity;
import com.xbongbong.paas.log.model.LoginLogModel;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 登录日志相关model方法实现
 * @author kaka
 * @date 2019/1/21 13:53
 * @since v1.0
 * @version v1.0
 */
@Service("loginLogModel")
public class LoginLogModelImpl implements LoginLogModel {

    private static final Logger LOG = LoggerFactory.getLogger(LoginLogModelImpl.class);

    @Resource
    private MongoTemplate mongoTemplate;

    /**
     * 保存登录日志
     * @param entity 登录日志实体
     */
    @Override
    @Async(value = "sysLogThreadPool")
    public Integer insert(LoginLogEntity entity) throws XbbException {
        try {
            mongoTemplate.save(entity);
        } catch (Exception e) {
            LOG.error("LoginLogModelImpl.insert 执行出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }

        return 1;
    }

    @Override
    public Integer update(LoginLogEntity entity) throws XbbException {
        // 目前不支持更新日志
        return null;
    }

    /**
     * 查询登录日志
     * @param param 查询条件
     * @return 返回命中的登录日志
     */
    @Override
    public List findEntitys(Map<String, Object> param) {
        return findEntitys(param,false);
    }

    @Override
    public List findEntitys(Map<String, Object> param, boolean isExport) {
        MongoQueryConditions conditions = MongoLogUtil.formatLoginLogQueryConditions(param);
        Query query = MongoLogUtil.formatQuery(conditions,isExport);
        return mongoTemplate.find(query, LoginLogEntity.class);
    }

    @Override
    public Integer getEntitysCount(Map<String, Object> param) {
        MongoQueryConditions conditions = MongoLogUtil.formatLoginLogQueryConditions(param);
        Query query = MongoLogUtil.formatQuery(conditions,false);
        // count 不需要limit和skip参数,新版本mongodb可能出错
        query.limit(-1);
        query.skip(0);
        return (int) mongoTemplate.count(query, LoginLogEntity.class);
    }

    @Override
    public List findEntitysWithoutSub(Map<String, Object> param) {
        return null;
    }

    @Override
    public Integer getUserLoginCount(String corpid,Integer startTime, Integer entTime) {
        Criteria criteria = Criteria.where("corpid").is(corpid).and("addTime").gte(startTime).lt(entTime);
        Aggregation customerAgg = Aggregation.newAggregation(
                Aggregation.match(criteria),
                Aggregation.group("userId").count().as("count"));
        AggregationResults<JSONObject> aggregationResults = mongoTemplate.aggregate(customerAgg, LoginLogEntity.class, JSONObject.class);

        List result = null;
        if(!Objects.isNull(aggregationResults.getRawResults())){
            // springData 升级之后,mongoTemplate 把 节点名称从"result" 改为了 “results”,真坑爹啊
            result = (List) aggregationResults.getRawResults().get("results");
        }
        return result == null?0:result.size();
    }

    @Override
    public List<LoginLogEntity> getUserLogin(String corpid,Integer startTime, Integer entTime) {
        Criteria criteria = Criteria.where("corpid").is(corpid).and("addTime").gte(startTime).lt(entTime);
        Query query = new Query();
        query.addCriteria(criteria);
        return mongoTemplate.find(query, LoginLogEntity.class);
    }
}
